package com.services.aidl;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.util.Log;
import android.widget.RemoteViews;

import com.videoplayer.R;

public class DownLoadService extends Service {

	private static final String TAG = "Obatu_DownLoad_Service"; // Log tag
	private final static int UPDATE_NOTIFY_PROGRESS = 3; // handler 标识：更新进度
	private final static int UPDATE_NOTIFY_COMPLETE = 4; // handler
															// 标识：更新进度条到完成状态（100%）
	private final static int DOWNLOAD_EXCEPTION_NOTIFY = 6; // handler
															// 标识：下载发送异常，如IO异常
	private final static int DOWNLOAD_FILE_SIZE = 1024 * 10; // 下载块大小：1K

	private NotificationManager nManager; // 状态栏提醒管理器
	private Map<Integer, Queue> queueList; // 队列列表
	private String CurrentName = "";
	private String lastName = "";
	private int currentProgress = 0;

	@Override
	public IBinder onBind(Intent arg0) {
		// 返回IDownLoadService.aidl接口实例
		Log.v("Services", "Service Start");
		return mBinder;
	}

	@Override
	public void onCreate() {
		// 初始化
		super.onCreate();
		nManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
		queueList = new HashMap<Integer, Queue>();
	}

	/**
	 * 新开一个下载进程
	 **/
	private void startDownLoad(final Queue queue) {
		if (queue.isCancel()) {
			// 如果已经取消则不进行
			return;
		}
		this.queueList.put(queue.getId(), queue);// 添加到队列

		new Thread() {
			@Override
			public void run() {
				downLoad(queue);
			}
		}.start();
	}

	/**
	 * 下载具体方法
	 **/
	private void downLoad(Queue queue) {
		CurrentName = queue.getName();
		Notification notify = null; // 创建一个notify

		// 创建一个新的notify实例，如果队列定义了downingIntent，则加入该intent到notify，
		// 否则指向服务本身
		if (queue.getDowningIntent() != null
				&& !queue.getDowningIntent().equals("")) {
			notify = newNotification(queue.getName(),
					new Intent(queue.getDowningIntent()),
					Notification.FLAG_NO_CLEAR, 100);
		} else {
			notify = newNotification(queue.getName(), new Intent(
					DownLoadService.this, DownLoadService.class),
					Notification.FLAG_NO_CLEAR, 100);
		}

		// 更新notify进度为0
		updateProgressBar(queue.getId(), UPDATE_NOTIFY_PROGRESS, 0, notify);

		// 定义URL下载用的一些变量
		HttpURLConnection urlConn = null;
		InputStream inputStream = null;
		File file = new File(queue.getSavePath());
		new File(file.getParent()).mkdirs(); // 创建目录
		Log.e(TAG, "0000000000" + file.getParent());
		OutputStream output = null;

		try {
			URL url = new URL(queue.getUrl());
			urlConn = (HttpURLConnection) url.openConnection();
			inputStream = urlConn.getInputStream();
			output = new FileOutputStream(file);
			byte[] buffer = new byte[DOWNLOAD_FILE_SIZE];

			long length = urlConn.getContentLength();

			queueList.get(queue.getId()).setFileLength(length); // 更新队列中Queue的文件长度

			long downSize = 0;
			float totalSize = length;

			int percent = 0;
			do {
				int numread = inputStream.read(buffer);
				if (numread == -1) {
					break;
				}
				output.write(buffer, 0, numread);

				downSize += numread;
				queueList.get(queue.getId()).setDownSize(downSize); // 更新队列中Queue的已下载大小

				int nowPercent = (int) ((downSize / totalSize) * 100);

				// 如果百分比有变动则更新进度条
				if (nowPercent > percent) {
					percent = nowPercent;
					updateProgressBar(queue.getId(), UPDATE_NOTIFY_PROGRESS,
							nowPercent, notify);
				}

				// 如果取消则停止下载
				if (queueList.get(queue.getId()).isCancel()) {
					nManager.cancel(queue.getId());
					file.delete();
					break;
				}

			} while (true);

			// 如果取消则停止下载，否则保存文件，并更新notify到完成状态
			if (!queueList.get(queue.getId()).isCancel()) {
				output.flush();
				if (queue.getCompleteIntent() != null
						&& !("").equals(queue.getCompleteIntent())) {
					notify.contentIntent = PendingIntent.getActivity(
							getApplicationContext(), 0,
							new Intent(queue.getCompleteIntent()),
							PendingIntent.FLAG_UPDATE_CURRENT);
				}
				updateProgressBar(queue.getId(), UPDATE_NOTIFY_COMPLETE, 100,
						notify);
			} else {
				nManager.cancel(queue.getId());
			}

		} catch (Exception e) {
			// 更新notify状态到异常
			updateProgressBar(queue.getId(), DOWNLOAD_EXCEPTION_NOTIFY, 100,
					notify);
			queueList.get(queue.getId()).setCancel(true);
			Log.e(TAG, e.toString(), e);
			e.printStackTrace();
		} finally {
			try {
				output.close();
				inputStream.close();
			} catch (IOException e) {
				e.printStackTrace();
			} catch (Exception ex) {
				ex.printStackTrace();
			}
		}
		// 是否完成后自动运行completeIntent
		if (!queueList.get(queue.getId()).isCancel()
				&& queueList.get(queue.getId()).isAutoRun()) {
			if (queue.getCompleteIntent() != null
					&& !("").equals(queue.getCompleteIntent())) {
				getApplicationContext().startActivity(
						new Intent(queue.getCompleteIntent()));
			}
		}
		// 队列中移除
		queueList.remove(queue.getId());
	}

	/**
	 * 更新队列
	 * 
	 * @param int notifyId 需要更新的notify id
	 * @param int what handler更新标识
	 * @param int progress 进度条刻度
	 * @param Notification
	 *            notify notify实例
	 **/
	private void updateProgressBar(int notifyId, int what, int progress,
			Notification notify) {
		// 从消息池取一条设定参数的消息
		Message msg = Message.obtain(handler, what, progress, notifyId, notify);
		handler.sendMessage(msg);
	}

	// 消息处理，主要更新notify的contentView对象的UI
	private Handler handler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			Notification notify = (Notification) msg.obj;
			int notifi_id = msg.arg2;
			switch (msg.what) {
			case UPDATE_NOTIFY_PROGRESS:
				Notification notifi = (Notification) msg.obj;
				int size = msg.arg1;
				notifi.contentView.setProgressBar(R.id.downloadProgress, 100,
						size, false);
				currentProgress = size;
				notifi.contentView.setTextViewText(R.id.percetText, size + "%");
				nManager.notify(notifi_id, notifi);
				break;
			case UPDATE_NOTIFY_COMPLETE:
				notify.flags = Notification.FLAG_AUTO_CANCEL;
				notify.contentView.setProgressBar(R.id.downloadProgress, 100,
						100, false);
				notify.contentView.setTextViewText(R.id.percetText, "完成");
				nManager.notify(notifi_id, notify);
				Intent intent = new Intent("com.services.download");
				intent.putExtra("id", notifi_id);
				sendBroadcast(intent);
				nManager.cancel(notifi_id);
				lastName = CurrentName;
				break;
			case DOWNLOAD_EXCEPTION_NOTIFY:
				notify.flags = Notification.FLAG_AUTO_CANCEL;
				notify.icon = android.R.drawable.stat_notify_error;
				notify.contentView.setImageViewResource(R.id.downloadImg,
						android.R.drawable.stat_sys_warning);
				notify.contentView
						.setTextViewText(R.id.percetText, "发生异常，停止下载");
				notify.contentView.setTextColor(R.id.downloadText, Color.RED);
				notify.contentIntent = PendingIntent.getActivity(
						getApplicationContext(), 0, new Intent(
								DownLoadService.this, DownLoadService.class),
						PendingIntent.FLAG_UPDATE_CURRENT);
				nManager.notify(notifi_id, notify);
				break;
			}
			super.handleMessage(msg);
		}
	};

	/**
	 * 创建一个新notify
	 * 
	 * @param String
	 *            tickText 显示在进度条上的文字标题
	 * @param Intent
	 *            intent 绑定的intent
	 * @param int flag notification标识:是否可以被自动清除
	 * @param int progressMax 最大进度条刻度
	 **/
	private Notification newNotification(String tickText, Intent intent,
			int flag, int progressMax) {
		@SuppressWarnings("deprecation")
		Notification notification = new Notification(
				android.R.drawable.stat_sys_download, tickText,
				System.currentTimeMillis());
		notification.flags = flag;
		notification.contentView = new RemoteViews(getPackageName(),
				R.layout.download_progress);
		notification.contentView.setProgressBar(R.id.downloadProgress,
				progressMax, 0, false);
		notification.contentView.setTextViewText(R.id.downloadText, tickText);

		final Context cxt = getApplicationContext();
		PendingIntent contentIntent = PendingIntent.getActivity(cxt, 0, intent,
				PendingIntent.FLAG_UPDATE_CURRENT);
		notification.contentIntent = contentIntent;
		return notification;
	}

	// IDownLoadService接口的实现，该接口提供对外访问接口
	IDownLoadService.Stub mBinder = new IDownLoadService.Stub() {

		@Override
		public void down(Queue queue) throws RemoteException {
			// 添加一个队列到下载服务中
			new File(new File(queue.getSavePath()).getParent()).mkdirs();
			startDownLoad(queue);
		}

		@Override
		public boolean isDownLoading(int id) throws RemoteException {
			if (queueList.containsKey(id) && !queueList.get(id).isCancel()) {
				return true;
			}
			return false;
		}

		@Override
		public void cancelQueue(int id) throws RemoteException {
			// 取消下载
			if (queueList.containsKey(id)) {
				queueList.get(id).setCancel(true);
			}
		}

		@Override
		public List<Queue> getQueueList() throws RemoteException {
			// 获取下载队列，客户端通过该方法获取当前下载队列信息，结合cancelQueue，可以实现取消下载
			List<Queue> list = new ArrayList<Queue>();
			for (Iterator<Entry<Integer, Queue>> it = queueList.entrySet()
					.iterator(); it.hasNext();) {
				Entry<Integer, Queue> entry = it.next();
				if (!entry.getValue().isCancel()) {
					list.add(entry.getValue());
				}
			}
			return list;
		}

		@Override
		public int getProgress() throws RemoteException {
			// TODO Auto-generated method stub
			return currentProgress;
		}

		@Override
		public String getCurrentName() throws RemoteException {
			// TODO Auto-generated method stub
			return CurrentName;
		}

		@Override
		public boolean isSplit() throws RemoteException {
			// TODO Auto-generated method stub
			return false;
		}

	};

	@Override
	public boolean onUnbind(Intent intent) {
		// 解绑，解绑时清理已经取消下载的notification
		for (Iterator<Entry<Integer, Queue>> it = queueList.entrySet()
				.iterator(); it.hasNext();) {
			Entry<Integer, Queue> entry = it.next();
			Queue queue = entry.getValue();
			if (!queue.isCancel()) {
				nManager.cancel(queue.getId());
			}
		}
		return super.onUnbind(intent);
	}
}
